package com.proposition.paper.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.proposition.commons.constant.ErrorCode;
import com.proposition.commons.enums.PaperPattern;
import com.proposition.commons.enums.PaperType;
import com.proposition.commons.model.*;
import com.proposition.exam.service.ExamAcupointAdultService;
import com.proposition.exam.service.ExamAnswer10Service;
import com.proposition.paper.mapper.AcupointSortMapper;
import com.proposition.paper.mapper.PaperExamMapper;
import com.proposition.paper.mapper.PaperMapper;
import com.proposition.paper.service.impl.PaperServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.*;

/**
 * 试卷添加策略辅助类
 *
 * @author 杨凯
 * @create 2018-02-02 11:24
 **/
@Component
public abstract class AbstractPaperAddStrategy {

	@Autowired
	private PaperMapper paperMapper;
	@Autowired
	private PaperExamMapper paperExamMapper;

	@Autowired
	private ExamAcupointAdultService examAcupointAdultService;

	@Autowired
	private ExamAnswer10Service examAnswer10Service;


	private static final Logger logger = LoggerFactory.getLogger(PaperServiceImpl.class);


	/**
	 * 根据符号切割试题
	 *
	 * @param exam 试题
	 * @param opt  符号
	 * @return
	 */
	public String[] examSplit(String exam, String opt) {
		return exam.split(opt);
	}

	/**
	 * 截取试题Id前两位
	 *
	 * @param exam
	 * @return
	 */
	public String[] getExamCategory(String exam) {
		String[] examArr = exam.split(",");
		for (int i = 0; i < examArr.length; i++) {
			examArr[i] = examArr[i].substring(0, 2);
		}
		return examArr;
	}


	/**
	 * 检查穴位顺序是否正确
	 *
	 * @param exam
	 * @return
	 */
	public int checAcupointAdult(String[] exam) {
		//获取试题列表
		List<Integer> partArr = new ArrayList<Integer>();
		List<Integer> front = new ArrayList<Integer>();
		List<Integer> behind = new ArrayList<Integer>();
		List<String> meridianArr = new ArrayList<String>();
		for (String e : exam) {
			//从成人穴位中查找，如果没有则返回NULL 代表人工组卷没有按照组卷策略添加
			ExamAcupointAdult examAcupointAdult = examAcupointAdultService.selectById(e);
			if (null == examAcupointAdult) {
				return 3001;
			}
			//获取题干
			AcupointSort acupointSort = new AcupointSort();
			acupointSort.setTitle(examAcupointAdult.getStem());
			acupointSort = acupointSort.selectOne(new EntityWrapper().eq("title", examAcupointAdult.getStem()));
			partArr.add(acupointSort.getPart());
			meridianArr.add(examAcupointAdult.getMeridianAdult());
		}

		//判断部位
		for (int i = 0; i < partArr.size() - 1; i++) {
			//将部位分为前后
			if (partArr.get(i) % 2 == 0) {
				behind.add(partArr.get(i));
			} else {
				front.add(partArr.get(i));
			}
		}

		for (int i = 0; i < behind.size() - 1; i++) {
			for (int j = i + 1; j < behind.size(); j++) {
				//如果两个题部位顺序不一样或者相同部位则不正确
				if (behind.get(i) >= behind.get(j)) {
					//部位顺序有问题
					return 3002;
				}
			}
		}

		for (int i = 0; i < front.size() - 1; i++) {
			for (int j = i + 1; j < front.size(); j++) {
				//如果两个题部位顺序不一样或者相同部位则不正确
				if (front.get(i) >= front.get(j)) {
					//部位顺序有问题
					return 3002;
				}
			}
		}

		//判断归经有没有重复
		for (int i = 0; i < meridianArr.size() - 1; i++) {
			for (int j = i + 1; j < meridianArr.size(); j++) {
				//不能为相同经络
				if (meridianArr.get(i).equals(meridianArr.get(j))) {
					return 3003;
				}
			}
		}
		return ErrorCode.SUCCESS;
	}


	/**
	 * 判断手法部位是否正确
	 *
	 * @param exam
	 * @return
	 */
	public int checkTechnique(String[] exam) {
		List<Integer> techniqueId = new ArrayList<Integer>();

		for (String examId : exam) {
			//从手法中查找该试题
			ExamAnswer10 examAnswer10 = examAnswer10Service.selectById(examId);
			if (null == examAnswer10) {
				logger.warn("手法查询对象为空");
				return 3005;
			}
			techniqueId.add(examAnswer10.getSinglePloyFiveCategoryId());
		}
		//判断类型有没有重复
		for (int i = 0; i < techniqueId.size() - 1; i++) {
			for (int j = i + 1; j < techniqueId.size(); j++) {
				if (techniqueId.get(i).equals(techniqueId.get(j))) {
					logger.warn("单项手法部位重复");
					return 3006;
				}
			}
		}
		return ErrorCode.SUCCESS;
	}


	/**
	 * 检测试题是否已使用
	 *
	 * @param paperPattern
	 * @param paperId
	 * @return
	 */
	public boolean checkExamIsUse(PaperPattern paperPattern, int examNumber, String paperId) {
		boolean flag = false;
		//获取当前年度
		int year = Calendar.getInstance().get(Calendar.YEAR);
		int batch = generatePaperBatch(paperPattern, null);
		List<String> list = paperMapper.checkExamIsUse(paperPattern, year, batch);
		if (null != list && !list.isEmpty()) {
			List<PaperExam> examList = paperExamMapper.selectList(new EntityWrapper<PaperExam>().in("paper_id", list));
			for (PaperExam paperExam : examList) {
				if (examNumber == 1) {
					if (paperExam.getExam1().equals(paperId)) {
						flag = true;
						return flag;
					}
				} else if (examNumber == 2) {
					if (paperExam.getExam2().equals(paperId)) {
						flag = true;
						return flag;
					}
				} else if (examNumber == 3) {
					if (paperExam.getExam3().equals(paperId)) {
						flag = true;
						return flag;
					}
				}

			}
		}
		return flag;
	}


	/**
	 * 获取已使用数量
	 *
	 * @param examCategory
	 * @return
	 */
	public int selectUsedByPaperId(PaperPattern paperPattern, int questionNumber, String examCategory) {
		int count = 0;
		//获取当前年度
		int year = Calendar.getInstance().get(Calendar.YEAR);
		int batch = generatePaperBatch(paperPattern, null);
		List<String> list = paperMapper.checkExamIsUse(paperPattern, year, batch);
		if (null != list && !list.isEmpty()) {
			List<PaperExam> examList = paperExamMapper.selectList(new EntityWrapper<PaperExam>().in("paper_id", list));
			for (PaperExam paperExam : examList) {
				if (questionNumber == 1) {
					if (paperExam.getExam1().substring(0, 2).equals(examCategory)) {
						count += 1;
					}
				} else if (questionNumber == 2) {
					if (paperExam.getExam2().substring(0, 2).equals(examCategory)) {
						count += 1;
					}
				} else if (questionNumber == 3) {
					if (paperExam.getExam3().substring(0, 2).equals(examCategory)) {
						count += 1;
					}
				}

			}
		}
		return count;
	}

	/**
	 * 判断数组中是否有重复值
	 *
	 * @param array
	 * @return
	 */
	public boolean checkRepeat(String[] array) {
		Set<String> set = new HashSet<String>();
		for (String str : array) {
			set.add(str);
		}
		if (set.size() != array.length) {
			//有重复
			return false;
		} else {
			//不重复
			return true;
		}
	}

	/**
	 * 判断数组值是否全部相同
	 */
	public boolean isIdentical(String[] array) {
		for (int i = 0; i < array.length - 1; i++) {
			if (!array[i].equals(array[i + 1])) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 生成试卷批次
	 *
	 * @param pattern
	 * @param paperType
	 * @return
	 */
	public int generatePaperBatch(PaperPattern pattern, PaperType paperType) {
		int year = Calendar.getInstance().get(Calendar.YEAR);
		int batch;
		int count;
		//获取最新的批次
		Paper paper = paperMapper.selectBatch(pattern, paperType, year);

		Wrapper wrapper = new EntityWrapper<Paper>();
		wrapper.eq("paper_pattern", pattern)
				.eq("year", year);
		if (!ObjectUtils.isEmpty(paper)) {
			wrapper.eq("batch", paper.getBatch());
		}
		count = paperMapper.selectCount(wrapper);
		if (count == 0) {
			//如果本年度没有进行组卷，那么批次为1
			batch = 1;
		} else if (count == 40) {
			batch = paper.getBatch() + 1;
		} else {
			batch = paper.getBatch();
		}

		return batch;
	}
}
